home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / Apple Game Sprockets / Examples / DrawSprocketTest / DrawSprocketTest.c
Encoding:
C/C++ Source or Header  |  1996-05-16  |  41.0 KB  |  1,493 lines  |  [TEXT/CWIE]

  1. /*
  2. ********************************************************************************
  3. **
  4. ** Name: DrawSprocketTest.c
  5. **
  6. ** Author(s):    Cary Farrier (CF)
  7. **
  8. ** Description:
  9. **
  10. **    Simple console window application to test the functionality of
  11. **    DrawSprocket.  This application does operations that one would not
  12. **    normally do when using DrawSprocket in a game, for example providing
  13. **    bogus input parameters.
  14. **
  15. ********************************************************************************
  16. **
  17. ** Revision History
  18. **
  19. ** 23-Apr-96    CF    Converted to final DS naming.
  20. **
  21. ********************************************************************************
  22. */
  23. #include <Quickdraw.h>
  24. #include <Events.h>
  25. #include <Fonts.h>
  26. #include <Memory.h>
  27. #include <Windows.h>
  28. #include <Menus.h>
  29. #include <TextEdit.h>
  30. #include <Dialogs.h>
  31. #include <Displays.h>
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include <math.h>
  37. #include <sioux.h>
  38.  
  39. #include "DrawSprocket.h"
  40.  
  41. /*
  42. ********************************************************************************
  43. ** constants
  44. ********************************************************************************
  45. */
  46. #define kRectSize 16
  47.  
  48. /*
  49. ********************************************************************************
  50. ** globals
  51. ********************************************************************************
  52. */
  53. Boolean gAutopilot = false;
  54. char gTextBuffer[512];
  55.  
  56. /*
  57. ********************************************************************************
  58. ** prototypes
  59. ********************************************************************************
  60. */
  61. void main( void );
  62. void ErrorMessage( char *inMessage, OSStatus inError );
  63. void DumpContextAttributes( DSpContextAttributes *inAttributes );
  64. void MyInitAttributes( DSpContextAttributes *inAttributes );
  65.  
  66. void TestDrawSprocket( void );
  67. void TestContextIteration( void );
  68. void TestContextSearchingAuto( void );
  69. void TestContextSearchingManual( void );
  70. void TestContextBuffering( Boolean inUseUnderlay, Boolean inUseOverlay,
  71.             Boolean inUseScaling );
  72. void TestContextCLUT( void );
  73. void TestUserSelectContext( void );
  74.  
  75. /*
  76. ********************************************************************************
  77. ** support routines
  78. ********************************************************************************
  79. */
  80. #pragma mark ##### support routines #####
  81.  
  82. /*
  83. ********************************************************************************
  84. **
  85. ** Name: main
  86. **
  87. ** Description:
  88. **
  89. **    Program entry point.  Starts up and shuts down DrawSprocket.
  90. **
  91. ********************************************************************************
  92. */
  93. void
  94. main( void )
  95. {
  96.     OSStatus theError;
  97.     
  98.     /* tell SIOUX to shut up */
  99.     SIOUXSettings.autocloseonquit = true;
  100.     SIOUXSettings.asktosaveonclose = false;
  101.     
  102.     /* startup DrawSprocket */
  103.     theError = DSpStartup();
  104.     if( theError )
  105.     {
  106.         ErrorMessage( "DSpStartup()", theError );
  107.         return;
  108.     }
  109.     
  110.     /* main test menu */
  111.     TestDrawSprocket();
  112.     
  113.     /* shutdown draw sprocket */
  114.     theError = DSpShutdown();
  115.     if( theError )
  116.         ErrorMessage( "DSpShutdown()", theError );
  117.  
  118. }
  119.  
  120. /*
  121. ********************************************************************************
  122. **
  123. ** Name: ErrorMessage
  124. **
  125. ** Description:
  126. **
  127. **    Prints an error message in human-readable form.
  128. **
  129. ********************************************************************************
  130. */
  131. void
  132. ErrorMessage(
  133.     char *inMessage,    /* message to display with error code        */
  134.     OSStatus inError    /* error code                                */
  135. )
  136. {
  137.     UInt32 theIndex;
  138.     static char *theErrorTexts[] = {
  139.         "Unknown Error",
  140.         "kDSpNotInitializedErr",
  141.         "kDSpSystemSWTooOldErr",
  142.         "kDSpInvalidContextErr",
  143.         "kDSpInvalidAttributesErr",
  144.         "kDSpContextAlreadyReservedErr",
  145.         "kDSpContextNotReservedErr",
  146.         "kDSpContextNotFoundErr",
  147.         "kDSpFrameRateNotReadyErr",
  148.         "kDSpConfirmSwitchWarning",
  149.         "kDSpInternalErr"
  150.     };
  151.     
  152.     /* convert the error code into an array index */    
  153.     if( inError <= kDSpNotInitializedErr &&
  154.         inError >= kDSpInternalErr )
  155.     {
  156.         theIndex = kDSpNotInitializedErr - inError + 1;
  157.     }
  158.     else
  159.         theIndex = 0;
  160.     
  161.     /* print the message */
  162.     printf("# Error %d (%s) encountered: %s\n", inError,
  163.         theErrorTexts[theIndex], inMessage );
  164.     
  165.     return;
  166. }
  167.  
  168. /*
  169. ********************************************************************************
  170. **
  171. ** Name: DumpContextAttributes
  172. **
  173. ** Description:
  174. **
  175. **    Display the contents of a DSpContextAttributes structure.
  176. **
  177. ********************************************************************************
  178. */
  179. void
  180. DumpContextAttributes(
  181.     DSpContextAttributes *inAttributes        /* attributes to show */
  182. )
  183. {
  184.     printf("\t             frequency : ");
  185.     if( inAttributes->frequency )
  186.         printf( "%dhz\n", inAttributes->frequency>>16 );
  187.     else
  188.         printf( "(unknown)\n" );
  189.     printf("\t          displayWidth : %d\n", inAttributes->displayWidth );
  190.     printf("\t         displayHeight : %d\n", inAttributes->displayHeight );
  191.     
  192.     printf("\t            colorNeeds : ");
  193.     switch( inAttributes->colorNeeds )
  194.     {
  195.         case kDSpColorNeeds_DontCare:
  196.             printf("kDSpColorNeeds_DontCare\n");
  197.             break;
  198.     
  199.         case kDSpColorNeeds_Request:
  200.             printf("kDSpColorNeeds_Request\n");
  201.             break;
  202.     
  203.         case kDSpColorNeeds_Require:
  204.             printf("kDSpColorNeeds_Require\n");
  205.             break;
  206.     
  207.         default:
  208.             printf(" %d (Unknown)\n", inAttributes->colorNeeds );
  209.             break;
  210.     }
  211.     
  212.     printf("\t            colorTable : 0x%X\n", inAttributes->colorTable );
  213.     
  214.     printf("\t        contextOptions : \n");
  215.     if( inAttributes->contextOptions & kDSpContextOption_QD3DAccel )
  216.         printf("\t                         kDSpContextOption_QD3DAccel\n");
  217.     if( inAttributes->contextOptions & kDSpContextOption_PageFlip )
  218.         printf("\t                         kDSpContextOption_PageFlip\n");
  219.     if( inAttributes->contextOptions & kDSpContextOption_TripleBuffer )
  220.         printf("\t                         kDSpContextOption_TripleBuffer\n");
  221.     if( 0 == inAttributes->contextOptions )
  222.         printf("\t                     (no options set)\n");
  223.         
  224.     printf("\t   backBufferDepthMask : 0x%X\n", inAttributes->backBufferDepthMask );
  225.     printf("\t      displayDepthMask : 0x%X\n", inAttributes->displayDepthMask );
  226.     printf("\t   backBufferBestDepth : %d\n", inAttributes->backBufferBestDepth );
  227.     printf("\t      displayBestDepth : %d\n", inAttributes->displayBestDepth );
  228.     printf("\t             pageCount : %d\n", inAttributes->pageCount );
  229.     
  230.     printf("\t gameMustConfirmSwitch : ");
  231.     if( inAttributes->gameMustConfirmSwitch )
  232.         printf("TRUE\n");
  233.     else
  234.         printf("FALSE\n");
  235. }
  236.  
  237. /*
  238. ********************************************************************************
  239. **
  240. ** Name: MyInitAttributes
  241. **
  242. ** Description:
  243. **
  244. **    Initialize a context attributes structure so that there is no garbage
  245. **    data in it.  This is important to do because DS will return an error
  246. **    if some fields are set incorrectly (including the "reserved" fields not
  247. **    being set to zero), and some things can actually cause a crash (such
  248. **    as a bogus color table handle).
  249. **
  250. ********************************************************************************
  251. */
  252. void
  253. MyInitAttributes(
  254.     DSpContextAttributes *inAttributes        /* attr structure to init */
  255. )
  256. {
  257.     if( NULL == inAttributes )
  258.         DebugStr("\pStimpy! You Idiot!");
  259.         
  260.     inAttributes->frequency                    = 0;
  261.     inAttributes->displayWidth                = 0;
  262.     inAttributes->displayHeight                = 0;
  263.     inAttributes->reserved1                    = 0;
  264.     inAttributes->reserved2                    = 0;
  265.     inAttributes->colorNeeds                = 0;
  266.     inAttributes->colorTable                = NULL;
  267.     inAttributes->contextOptions            = 0;
  268.     inAttributes->backBufferDepthMask        = 0;
  269.     inAttributes->displayDepthMask            = 0;
  270.     inAttributes->backBufferBestDepth        = 0;
  271.     inAttributes->displayBestDepth            = 0;
  272.     inAttributes->pageCount                    = 0;
  273.     inAttributes->gameMustConfirmSwitch        = false;
  274.     inAttributes->reserved3[0]                = 0;
  275.     inAttributes->reserved3[1]                = 0;
  276.     inAttributes->reserved3[2]                = 0;
  277.     inAttributes->reserved3[3]                = 0;
  278. }
  279.  
  280. /*
  281. ********************************************************************************
  282. ** test routines
  283. ********************************************************************************
  284. */
  285. #pragma mark ##### test routines #####
  286.  
  287. /*
  288. ********************************************************************************
  289. **
  290. ** Name: TestDrawSprocket
  291. **
  292. ** Description:
  293. **
  294. **    Main test dispatcher for the DrawSprocket test routines.
  295. **
  296. ********************************************************************************
  297. */
  298. void
  299. TestDrawSprocket( void )
  300. {
  301.     Boolean theDoneFlag = false;
  302.     
  303.     while( false == theDoneFlag )
  304.     {
  305.         UInt32 theChoice;
  306.         
  307.         printf("\n\n############################################################\n");
  308.         printf("DrawSprocket test application.\n");
  309.         printf("Please select from the following tests:\n");        
  310.         
  311.         printf("\t 1. Exit\n");
  312. //        printf("\t 2. Run all tests automatically\n");
  313. //        printf("\t 3. Dump information needed for DrawSprocket bug reports\n");
  314.         printf("\t 4. Display/context iteration\n");
  315.         printf("\t 5. Context searching (auto selection of w/h/d/d)\n");
  316.         printf("\t 6. Context searching (you specify w/h/d/d)\n");
  317.         printf("\t 7. Multiple-buffering/page flipping (640x480x8)\n");
  318.         printf("\t 8. CLUT operations\n");
  319.         printf("\t 9. DSpUserSelectContext\n");
  320.         printf("\t10. Underlays\n");
  321.         printf("\t11. Overlays\n");
  322.         printf("\t12. Overlays & Underlays\n");
  323.         printf("\t13. Pixel Scaling\n");
  324.         
  325.         printf("\n\tSelection: ");
  326.         gets( gTextBuffer );
  327.         theChoice = atoi( gTextBuffer );
  328.         switch( theChoice )
  329.         {
  330.             /* exit */
  331.             case 1:
  332.                 theDoneFlag = true;
  333.                 break;
  334.                 
  335.             /* context iteration */
  336.             case 4:
  337.                 TestContextIteration();
  338.                 break;            
  339.             
  340.             /* auto context searching */
  341.             case 5:
  342.                 TestContextSearchingAuto();
  343.                 break;
  344.  
  345.             /* manual context searching */
  346.             case 6:
  347.                 TestContextSearchingManual();
  348.                 break;
  349.                 
  350.             /* buffering */
  351.             case 7:
  352.                 TestContextBuffering( false, false, false );
  353.                 break;
  354.             
  355.             /* CLUT */
  356.             case 8:
  357.                 TestContextCLUT();
  358.                 break;
  359.             
  360.             /* user select context */
  361.             case 9:
  362.                 TestUserSelectContext();
  363.                 break;
  364.                         
  365.             /* underlay */
  366.             case 10:
  367.                 TestContextBuffering( true, false, false );
  368.                 break;
  369.             
  370.             /* overlay */
  371.             case 11:
  372.                 TestContextBuffering( false, true, false );
  373.                 break;
  374.             
  375.             /* overlay & underlay */
  376.             case 12:
  377.                 TestContextBuffering( true, true, false );
  378.                 break;
  379.             
  380.             /* overlay & underlay & scaling */
  381.             case 13:
  382.                 TestContextBuffering( true, true, true );
  383.                 break;
  384.             
  385.             /* unknown */
  386.             default:
  387.                 printf("\nhuh?\n");
  388.                 break;            
  389.         }
  390.         
  391.         printf("\nThank you, please drive through.\n");
  392.     }
  393. }
  394.  
  395. /*
  396. ********************************************************************************
  397. **
  398. ** Name: TestContextIteration
  399. **
  400. ** Description:
  401. **
  402. **    Test the ability of DrawSprocket to iterate through the available
  403. **    display devices and contexts.
  404. **
  405. ********************************************************************************
  406. */
  407. void
  408. TestContextIteration( void )
  409. {
  410.     GDHandle theGDevice;
  411.     OSStatus theError;
  412.     
  413.     printf("\n\n");
  414.     printf("############################################################\n");
  415.     printf("###          Testing Display/Context Iteration           ###\n");
  416.     printf("############################################################\n");
  417.     printf("\n\n");
  418.  
  419.     /*
  420.     ** Walk the list of display devices in the system.  DrawSprocket is
  421.     ** centered around the DisplayIDType, which is used by the Display
  422.     ** Manager.  The GDevice records are going to be in flux with future
  423.     ** versions of the system software, so it is best to make the change
  424.     ** now and make your software DisplayManager-centric.
  425.     */
  426.     theGDevice = DMGetFirstScreenDevice( false );
  427.     while( theGDevice )
  428.     {
  429.         DisplayIDType theDisplayID;
  430.         DSpContextReference theContext;
  431.         UInt32 theContextIndex = 0;
  432.         
  433.         /* get the display ID */
  434.         theError = DMGetDisplayIDByGDevice( theGDevice, &theDisplayID,
  435.             false );
  436.         if( theError )
  437.         {
  438.             ErrorMessage( "DMGetDisplayIDByGDevice", theError );
  439.             return;
  440.         }
  441.         
  442.         /* walk the list of contexts for this display */
  443.         theError = DSpGetFirstContext( theDisplayID, &theContext );
  444.         while( noErr == theError )
  445.         {
  446.             DSpContextAttributes theAttributes;
  447.             
  448.             /* obtain the context attributes */
  449.             theError = DSpContext_GetAttributes( theContext, &theAttributes );
  450.             if( theError )
  451.             {
  452.                 ErrorMessage( "DSpContext_GetAttributes", theError );
  453.                 return;
  454.             }
  455.             
  456.             /* display the attributes structure */
  457.             printf("Display %d, Context %d capabilities:\n", theDisplayID,
  458.                 theContextIndex++ );
  459.             DumpContextAttributes( &theAttributes );
  460.  
  461.             /*
  462.             ** get the next context.  when a kDSpContextNotFoundErr code
  463.             ** is returned we have hit the end of the context list.  if
  464.             ** a different error code is returned, something went wrong.
  465.             */
  466.             theError = DSpGetNextContext( theContext, &theContext );
  467.             if( theError && ( kDSpContextNotFoundErr != theError ) )
  468.             {
  469.                 ErrorMessage( "DSpGetNextContext", theError );
  470.                 return;
  471.             }
  472.         }
  473.  
  474.         /* next device */
  475.         theGDevice = DMGetNextScreenDevice( theGDevice, false );
  476.     }    
  477. }
  478.  
  479. /*
  480. ********************************************************************************
  481. **
  482. ** Name: TestContextSearchingAuto
  483. **
  484. ** Description:
  485. **
  486. **    Test the ability of DrawSprocket to find a context that matches
  487. **    the requested attributes.
  488. **
  489. ********************************************************************************
  490. */
  491. void TestContextSearchingAuto( void )
  492. {
  493.     DSpContextAttributes theDesiredAttributes;
  494.     DSpContextReference theContext;
  495.     OSStatus theError;
  496.     
  497.     printf("\n\n");
  498.     printf("############################################################\n");
  499.     printf("###          Testing Display/Context Searching           ###\n");
  500.     printf("############################################################\n");
  501.     printf("\n\n");
  502.  
  503.     /*
  504.     ** Find a 320x200x8 mode
  505.     **
  506.     ** First, init the attributes so that there will be no garbage in any
  507.     ** of the fields (and which will cause DS to return an error).  This
  508.     ** is especially important for fields that DS can't check, such as
  509.     ** the colorTable.  If the colorTable is bogus when a call to reserve
  510.     ** a context is made, then it will try to use the bogus color table
  511.     ** (causing unpleasant visits to the debugger).
  512.     **
  513.     ** When using DSpFindBestContext(), the attributes are interpreted as
  514.     ** *REQUIREMENTS*, unlike when you call DSpContext_Reserve(), when
  515.     ** they are interpreted as *REQUESTS*.  If I specify a contextOption
  516.     ** of kDSpContextOption_PageFlip here, only contexts with the ability
  517.     ** to page flip will be considered in the search, however if I specify
  518.     ** the same option when reserving the context, and page flipping is not
  519.     ** available, then DS will use software double/triple buffering.  This
  520.     ** is so to make it easy for the game to always request that DS use
  521.     ** page flipping if it is there (at reservation time), but still continue
  522.     ** if it is not.  Conversely, the game can search for only contexts
  523.     ** that meet a specific criteria, and know that any matches found will
  524.     ** meet those specifications.
  525.     */
  526.     MyInitAttributes( &theDesiredAttributes );
  527.     theDesiredAttributes.displayWidth            = 320;
  528.     theDesiredAttributes.displayHeight            = 200;
  529.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  530.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  531.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  532.     theDesiredAttributes.backBufferBestDepth    = 8;
  533.     theDesiredAttributes.displayBestDepth        = 8;
  534.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  535.     if( theError && kDSpContextNotFoundErr != theError )
  536.     {
  537.         ErrorMessage( "DSpFindBestContext 320x200x8", theError );
  538.         return;
  539.     }
  540.     if( kDSpContextNotFoundErr == theError )
  541.     {
  542.         printf("# Unable to find a matching context for the following attributes:\n");
  543.         DumpContextAttributes( &theDesiredAttributes );
  544.         return;
  545.     }
  546.     else
  547.     {
  548.         DSpContextAttributes theActualAttributes;
  549.         DisplayIDType theDisplayID;
  550.         
  551.         /* get the actual attributes for the context */
  552.         theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
  553.         if( theError )
  554.         {
  555.             ErrorMessage( "DSpContext_GetAttributes", theError );
  556.             return;
  557.         }
  558.  
  559.         /* get the display id for the context */
  560.         theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
  561.         if( theError )
  562.         {
  563.             ErrorMessage( "DSpContext_GetDisplayID", theError );
  564.             return;
  565.         }
  566.  
  567.         /* tell the user about the results */
  568.         printf("Best matching Context for the following attributes...\n");
  569.         DumpContextAttributes( &theDesiredAttributes );
  570.  
  571.         printf("...is the context on display id %d with these attributes:\n",
  572.             theDisplayID );
  573.         DumpContextAttributes( &theActualAttributes );
  574.     }
  575. }
  576.  
  577. /*
  578. ********************************************************************************
  579. **
  580. ** Name: TestContextSearchingManual
  581. **
  582. ** Description:
  583. **
  584. **    Test the ability of DrawSprocket to find a context that matches
  585. **    the requested attributes, but let the user choose the attributes.
  586. **
  587. ********************************************************************************
  588. */
  589. void TestContextSearchingManual( void )
  590. {
  591.     DSpContextAttributes theDesiredAttributes;
  592.     DSpContextReference theContext;
  593.     OSStatus theError;
  594.     
  595.     printf("\n\n");
  596.     printf("############################################################\n");
  597.     printf("###          Testing Display/Context Searching           ###\n");
  598.     printf("############################################################\n");
  599.     printf("\n\n");
  600.  
  601.     /* get the context attributes */
  602.     MyInitAttributes( &theDesiredAttributes );
  603.  
  604.     printf("enter the display width: ");
  605.     gets(gTextBuffer);
  606.     theDesiredAttributes.displayWidth            = atoi(gTextBuffer);
  607.     if( 0 == theDesiredAttributes.displayWidth )
  608.     {
  609.         printf("bogus value!\n");
  610.         return;
  611.     }
  612.     
  613.     printf("enter the display height: ");
  614.     gets(gTextBuffer);
  615.     theDesiredAttributes.displayHeight            = atoi(gTextBuffer);
  616.     if( 0 == theDesiredAttributes.displayHeight )
  617.     {
  618.         printf("bogus value!\n");
  619.         return;
  620.     }
  621.     
  622.     printf("enter the back buffer best depth: ");
  623.     gets(gTextBuffer);
  624.     theDesiredAttributes.backBufferBestDepth    = atoi(gTextBuffer);
  625.     if( 0 == theDesiredAttributes.backBufferBestDepth )
  626.     {
  627.         printf("bogus value!\n");
  628.         return;
  629.     }
  630.     
  631.     printf("enter the display best depth: ");
  632.     gets(gTextBuffer);
  633.     theDesiredAttributes.displayBestDepth        = atoi(gTextBuffer);
  634.     if( 0 == theDesiredAttributes.displayBestDepth )
  635.     {
  636.         printf("bogus value!\n");
  637.         return;
  638.     }
  639.     
  640.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  641.     theDesiredAttributes.backBufferDepthMask    = theDesiredAttributes.backBufferBestDepth;
  642.     theDesiredAttributes.displayDepthMask        = theDesiredAttributes.displayBestDepth;
  643.  
  644.     /* find the context */
  645.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  646.     if( theError && kDSpContextNotFoundErr != theError )
  647.     {
  648.         ErrorMessage( "DSpFindBestContext (Manual)", theError );
  649.         return;
  650.     }
  651.     if( kDSpContextNotFoundErr == theError )
  652.     {
  653.         printf("# Unable to find a matching context for the following attributes:\n");
  654.         DumpContextAttributes( &theDesiredAttributes );
  655.         return;
  656.     }
  657.     else
  658.     {
  659.         DSpContextAttributes theActualAttributes;
  660.         DisplayIDType theDisplayID;
  661.         
  662.         /* get the actual attributes for the context */
  663.         theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
  664.         if( theError )
  665.         {
  666.             ErrorMessage( "DSpContext_GetAttributes", theError );
  667.             return;
  668.         }
  669.  
  670.         /* get the display id for the context */
  671.         theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
  672.         if( theError )
  673.         {
  674.             ErrorMessage( "DSpContext_GetDisplayID", theError );
  675.             return;
  676.         }
  677.  
  678.         /* tell the user about the results */
  679.         printf("Best matching Context for the following attributes...\n");
  680.         DumpContextAttributes( &theDesiredAttributes );
  681.  
  682.         printf("...is the context on display id %d with these attributes:\n",
  683.             theDisplayID );
  684.         DumpContextAttributes( &theActualAttributes );
  685.     }
  686. }
  687.  
  688. /*
  689. ********************************************************************************
  690. **
  691. ** Name: TestContextBuffering
  692. **
  693. ** Description:
  694. **
  695. **    Test the ability of DrawSprocket to sw buffer or page flip an image.
  696. **
  697. ********************************************************************************
  698. */
  699. void TestContextBuffering(
  700.     Boolean inUseUnderlay,
  701.     Boolean inUseOverlay,
  702.     Boolean inUseScaling
  703. )
  704. {
  705.     DSpContextAttributes theDesiredAttributes;
  706.     DSpContextReference theContext;
  707.     OSStatus theError;
  708.     DSpAltBufferReference theUnderlay, theOverlay;
  709.     UInt32 theDisplayWidth, theDisplayHeight;
  710.     
  711.     printf("\n\n");
  712.     printf("############################################################\n");
  713.     printf("###                  Testing Buffering                   ###\n");
  714.     printf("############################################################\n");
  715.     printf("\n\n");
  716.  
  717.  
  718.     /* find the context */
  719.     MyInitAttributes( &theDesiredAttributes );
  720.     theDesiredAttributes.displayWidth            = 640;
  721.     theDesiredAttributes.displayHeight            = 480;
  722.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  723.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  724.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  725.     theDesiredAttributes.backBufferBestDepth    = 8;
  726.     theDesiredAttributes.displayBestDepth        = 8;
  727.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  728.     if( theError && kDSpContextNotFoundErr != theError )
  729.     {
  730.         ErrorMessage( "DSpFindBestContext", theError );
  731.         return;
  732.     }
  733.     if( kDSpContextNotFoundErr == theError )
  734.     {
  735.         printf("# Unable to find a matching context for the following attributes:\n");
  736.         DumpContextAttributes( &theDesiredAttributes );
  737.         return;
  738.     }
  739.  
  740.     theDisplayWidth = 640;
  741.     theDisplayHeight = 480;
  742.     
  743.     /*
  744.     ** Here is where I need to OR in the value to use page flipping.  If
  745.     ** I had used the value when calling DSpFindBestContext() then it would
  746.     ** have only considered displays that have page flipping hardware, but
  747.     ** I want to run with software buffering too.
  748.     */
  749.     theDesiredAttributes.contextOptions |= kDSpContextOption_PageFlip;
  750.  
  751.     /*
  752.     ** If page flipping isn't available, then software buffering will
  753.     ** be used.  DS can use double or triple buffering depending on the
  754.     ** state of the kDSpContextOption_TripleBuffer option bit.
  755.     **
  756.     ** If you only want double buffering, perhaps because of memory
  757.     ** constraints (a certain person named BG comes to mind, don't
  758.     ** go postal on me BG :-), then you should turn off the option bit.
  759.     **
  760.     ** If you leave the bit on and there is hardware page flipping
  761.     ** available (and you haven't turned off that option bit), but
  762.     ** there are only 2 video pages (not three) then DS will consider
  763.     ** page flipping to be more important of an option than triple
  764.     ** buffering and will drop you down to 2 VRAM pages (leaving you
  765.     ** still page flipping).
  766.     **
  767.     */
  768.     /*
  769.     theDesiredAttributes.contextOptions &= ~kDSpContextOption_TripleBuffer;
  770.     */
  771.     
  772.     /* reserve the context */    
  773.     theError = DSpContext_Reserve( theContext, &theDesiredAttributes );
  774.     if( theError )
  775.     {
  776.         ErrorMessage( "DSpContext_Reserve", theError );
  777.         return;
  778.     }
  779.     
  780.     if( inUseScaling )
  781.     {
  782.         theError = DSpContext_SetScale( theContext, kDSpBufferScale_2 );
  783.         if( theError )
  784.         {
  785.             ErrorMessage( "DSpContext_SetScale", theError );
  786.             return;
  787.         }
  788.         
  789.         theDisplayWidth = 320;
  790.         theDisplayHeight = 240;
  791.     }
  792.         
  793.     /*
  794.     ** allocate an alt buffer that will be used for the underlay.  An
  795.     ** underlay is useful in games that have a need to restore from a
  796.     ** static background.
  797.     */
  798.     if( inUseUnderlay )
  799.     {
  800.         theError = DSpAltBuffer_New( theContext, false, &theUnderlay );
  801.         if( theError )
  802.         {
  803.             DSpContext_Release( theContext );
  804.             ErrorMessage( "DSpAltBuffer_New (underlay)", theError );
  805.             return;
  806.         }
  807.         
  808.         theError = DSpContext_SetUnderlayAltBuffer( theContext, theUnderlay );
  809.         if( theError )
  810.         {
  811.             DSpContext_Release( theContext );
  812.             ErrorMessage( "DSpContext_SetUnderlayAltBuffer", theError );
  813.             return;
  814.         }
  815.     }
  816.     
  817.     /*
  818.     ** allocate an alt buffer that will be used as an overlay.  An overlay
  819.     ** is useful for things such as a cockpit view that is superimposed
  820.     ** on the back buffer before it is displayed.
  821.     */
  822.     if( inUseOverlay )
  823.     {
  824.         CGrafPtr theAltBufferPort;
  825.         GDHandle theAltBufferGDevice, theOldGDevice;
  826.         GrafPtr theOldPort;
  827.         
  828.         GetPort( &theOldPort );
  829.         theOldGDevice = GetGDevice();
  830.         
  831.         theError = DSpAltBuffer_New( theContext, false, &theOverlay );
  832.         if( theError )
  833.         {
  834.             DSpContext_Release( theContext );
  835.             ErrorMessage( "DSpAltBuffer_New (overlay)", theError );
  836.             return;
  837.         }
  838.         
  839.         theError = DSpContext_SetOverlayAltBuffer( theContext, theOverlay );
  840.         if( theError )
  841.         {
  842.             DSpContext_Release( theContext );
  843.             ErrorMessage( "DSpContext_SetOverlayAltBuffer", theError );
  844.             return;
  845.         }
  846.  
  847.         /*
  848.         ** fill the overlay buffer with a pattern
  849.         */
  850.         theError = DSpAltBuffer_GetCGrafPtr( theOverlay,
  851.             kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice );
  852.         if( theError )
  853.         {
  854.             ErrorMessage( "DSpAltBuffer_GetCGrafPtr (overlay)", theError );
  855.             DSpContext_Release( theContext );
  856.             return;
  857.         }
  858.         
  859.         /*
  860.         ** if you want to use QuickDraw or any other toolbox rendering
  861.         ** code, you must setup the GDevice as well as the port when
  862.         ** working with AltBuffers!
  863.         */
  864.         SetPort( (GrafPtr)theAltBufferPort );
  865.         SetGDevice( theAltBufferGDevice );
  866.         
  867.         ForeColor( redColor );
  868.         TextSize(96);
  869.         MoveTo( 100, 200 );
  870.         DrawText( "Overlay!", 0, 8 );
  871.         
  872.         SetPort( theOldPort );
  873.         SetGDevice( theOldGDevice );
  874.     }
  875.         
  876.     /*
  877.     ** If you are in a debug cycle, you may want to enable debugging mode
  878.     ** in DrawSprocket so that a fade out, followed by a break in the
  879.     ** debugger, won't leave you with nothing to see.
  880.     **
  881.     ** You can also create a folder in same folder as your game, and name
  882.     ** it "DSpSetDebugMode", this will also cause DSp to enter debug mode.
  883.     ** This method is handy if you don't want to rebuild your game with
  884.     ** the call just to debug it.
  885.     */
  886.     //DSpSetDebugMode( true );
  887.     
  888.     /*
  889.     ** fade out all displays to black, you must have at least one reserved
  890.     ** context to do this or you will get an error.  A game should always
  891.     ** fade to black before activating a context because if the activation
  892.     ** causes a resolution change the user will see a very ugly twitch in
  893.     ** the display.
  894.     */
  895.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  896.     if( theError )
  897.     {
  898.         ErrorMessage( "DSpContext_FadeGammaOut", theError );
  899.         DSpContext_FadeGammaIn( NULL, NULL );
  900.         DSpContext_Release( theContext );
  901.         return;
  902.     }
  903.     
  904.     /* put the context into the active state */
  905.     theError = DSpContext_SetState( theContext, kDSpContextState_Active );
  906.     if( theError )
  907.     {
  908.         ErrorMessage( "DSpContext_SetState", theError );
  909.         DSpContext_FadeGammaIn( NULL, NULL );
  910.         DSpContext_Release( theContext );
  911.         return;
  912.     }
  913.  
  914.     /* fade back in */
  915.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  916.     if( theError )
  917.     {
  918.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  919.         DSpContext_Release( theContext );
  920.         return;
  921.     }
  922.     
  923.     /*
  924.     ****************************************************************************
  925.     ** do the double buffering
  926.     ****************************************************************************
  927.     */
  928.     
  929.     /*
  930.     ** fill the underlay buffer with a pattern
  931.     */
  932.     if( inUseUnderlay )
  933.     {
  934.         UInt32 thePosition, theColorIndex, theXPos, theYPos;
  935.         CGrafPtr theAltBufferPort;
  936.         GDHandle theAltBufferGDevice, theOldGDevice;
  937.         GrafPtr theOldPort;
  938.         
  939.         GetPort( &theOldPort );
  940.         theOldGDevice = GetGDevice();
  941.         
  942.         /* set the alt buffer to be the current port */
  943.         theError = DSpAltBuffer_GetCGrafPtr( theUnderlay,
  944.             kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice );
  945.         if( theError )
  946.         {
  947.             ErrorMessage( "DSpAltBuffer_GetCGrafPtr (underlay)", theError );
  948.             DSpContext_FadeGammaIn( NULL, NULL );
  949.             DSpContext_Release( theContext );
  950.             return;
  951.         }
  952.         
  953.         /*
  954.         ** if you want to use QuickDraw or any other toolbox rendering
  955.         ** code, you must setup the GDevice as well as the port when
  956.         ** working with AltBuffers!
  957.         */
  958.         SetPort( (GrafPtr)theAltBufferPort );
  959.         SetGDevice( theAltBufferGDevice );
  960.  
  961.         /*
  962.         ** draw a pattern into the underlay buffer. this pattern will be
  963.         ** restored every time I get the back buffer
  964.         */
  965.         theColorIndex = 0;
  966.         for( theYPos = 0; theYPos < theDesiredAttributes.displayHeight;
  967.             theYPos += kRectSize )
  968.         {
  969.             for( theXPos = 0; theXPos < theDesiredAttributes.displayWidth;
  970.                 theXPos += kRectSize )
  971.             {
  972.                 Rect theRect;
  973.                 
  974.                 SetRect( &theRect, 0, 0, kRectSize, kRectSize );
  975.                 OffsetRect( &theRect, theXPos, theYPos );
  976.                 theAltBufferPort->fgColor = theColorIndex % 255;
  977.                 
  978.                 PaintRect( &theRect );
  979.  
  980.                 theColorIndex++;            
  981.             }
  982.         }
  983.  
  984.         SetPort( theOldPort );
  985.         SetGDevice( theOldGDevice );
  986.     }
  987.     
  988.     /*
  989.     ** this test slides a black vertical bar left and right on the
  990.     ** display, producing an image where any tearing is amplified.
  991.     */
  992.     {
  993.     
  994.     RGBColor theColor, theTextColor;
  995.     Rect theRectangleRect, theOldRect, theRect;
  996.     UInt32 theStartTick, theMaxTick, theCurrentTick;
  997.     UInt32 theCount, theRectangleDelta;
  998.     UInt32 theWidth, theXPos, theYPos;
  999.     CGrafPtr theBackBuffer;
  1000.     
  1001.     theColor.red = 0;
  1002.     theColor.green = 0;
  1003.     theColor.blue = 0;
  1004.     theTextColor.red = 0xFFFF;
  1005.     theTextColor.green = 0xFFFF;
  1006.     theTextColor.blue = 0xFFFF;
  1007.  
  1008.     /* rectangle will be 1/8 the display width, and all of the height */
  1009.     SetRect( &theRectangleRect, 0, 0, theDesiredAttributes.displayWidth >> 3,
  1010.         theDesiredAttributes.displayHeight );
  1011.     theOldRect = theRectangleRect;
  1012.     
  1013.     theStartTick = theCurrentTick = TickCount();
  1014.     theMaxTick = theStartTick + (15 * 60);
  1015.     theCount = 0;
  1016.     theRectangleDelta = 3;
  1017.     while( theCurrentTick < theMaxTick )
  1018.     {
  1019.         
  1020.         /* get the back buffer */
  1021.         theError = DSpContext_GetBackBuffer( theContext, kDSpBufferKind_Normal,
  1022.             &theBackBuffer );
  1023.         if( theError )
  1024.         {
  1025.             ErrorMessage( "DSpContext_GetBackBuffer", theError );
  1026.             DSpContext_Release( theContext );
  1027.             return;
  1028.         }
  1029.         
  1030.         /* set the back buffer to be the current port */
  1031.         SetPort( (GrafPtr)theBackBuffer );
  1032.         
  1033.         /*
  1034.         ** there is no need to erase the back buffer when I am using
  1035.         ** an underlay to restore the "clean" image
  1036.         */
  1037.         if( !inUseUnderlay )
  1038.             EraseRect( &theBackBuffer->portRect );
  1039.  
  1040.         /* fill the display with a sliding vertical rectangle */
  1041.         RGBForeColor( &theColor );        
  1042.         PaintRect( &theRectangleRect );
  1043.  
  1044.         /* inval the new and old rect positions */        
  1045.         theError = DSpContext_InvalBackBufferRect( theContext,
  1046.             &theRectangleRect );
  1047.         theError = DSpContext_InvalBackBufferRect( theContext,
  1048.             &theOldRect );
  1049.         theOldRect = theRectangleRect;
  1050.             
  1051.         if( (theRectangleRect.right + theRectangleDelta) > theDesiredAttributes.displayWidth )
  1052.             theRectangleDelta = -theRectangleDelta;
  1053.         
  1054.         if ( (theRectangleRect.left + theRectangleDelta) < 0 )
  1055.             theRectangleDelta = -theRectangleDelta;
  1056.  
  1057.         theRectangleRect.left += theRectangleDelta;
  1058.         theRectangleRect.right += theRectangleDelta;
  1059.  
  1060.         // draw a frame counter
  1061.         sprintf((char *)&gTextBuffer[1],
  1062.             "This is frame %d (%d ticks remaining, %.1f fps)",
  1063.             theCount + 1, theMaxTick - theCurrentTick,
  1064.             (float)(theCount / ((theCurrentTick - theStartTick) / 60.0)) );
  1065.         gTextBuffer[0] = strlen( (char *)&gTextBuffer[1] );
  1066.         theWidth = StringWidth( (ConstStr255Param)gTextBuffer );
  1067.         theXPos = ( theDisplayWidth >> 1 ) - ( theWidth >> 1 );
  1068.         theYPos = theDisplayHeight - 20;
  1069.  
  1070.         theTextColor.red = 0;
  1071.         theTextColor.green = 0;
  1072.         theTextColor.blue = 0;
  1073.         RGBForeColor( &theTextColor );
  1074.         SetRect( &theRect, theXPos - 10, theYPos - 20, theXPos + theWidth + 10, theYPos + 10 );
  1075.         PaintRect( &theRect );
  1076.         
  1077.         theError = DSpContext_InvalBackBufferRect( theContext,
  1078.             &theRect );
  1079.  
  1080.         theTextColor.red = 0;
  1081.         theTextColor.green = 0xFFFF;
  1082.         theTextColor.blue = 0xFFFF;
  1083.         RGBForeColor( &theTextColor );
  1084.         FrameRect( &theRect );
  1085.         
  1086.         MoveTo( theXPos, theYPos );
  1087.         DrawString( (ConstStr255Param)gTextBuffer );
  1088.         
  1089.         // swap the buffers
  1090.         theError = DSpContext_SwapBuffers( theContext, NULL, 0 );
  1091.         if( theError )
  1092.         {
  1093.             ErrorMessage( "DSpContext_SwapBuffers", theError );
  1094.             DSpContext_Release( theContext );
  1095.             return;
  1096.         }
  1097.         
  1098.         /* increase frame counter */
  1099.         theCount++;
  1100.         theCurrentTick = TickCount();
  1101.     }
  1102.  
  1103.     }
  1104.     
  1105.     /*
  1106.     ****************************************************************************
  1107.     ** cleanup
  1108.     ****************************************************************************
  1109.     */    
  1110.  
  1111.     /* fade to black */
  1112.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  1113.     if( theError )
  1114.     {
  1115.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1116.         DSpContext_Release( theContext );
  1117.         return;
  1118.     }
  1119.  
  1120.     /* remove the underlay & release it */
  1121.     if( inUseUnderlay )
  1122.     {
  1123.         DSpContext_SetUnderlayAltBuffer( theContext, NULL );
  1124.         DSpAltBuffer_Dispose( theUnderlay );
  1125.         theUnderlay = NULL;
  1126.     }
  1127.     
  1128.     /* remove the overlay & release it */
  1129.     if( inUseOverlay )
  1130.     {
  1131.         DSpContext_SetOverlayAltBuffer( theContext, NULL );
  1132.         DSpAltBuffer_Dispose( theOverlay );
  1133.         theOverlay = NULL;
  1134.     }
  1135.     
  1136.     /* put the context into the inactive state */
  1137.     theError = DSpContext_SetState( theContext, kDSpContextState_Inactive );
  1138.     if( theError )
  1139.     {
  1140.         ErrorMessage( "DSpContext_SetState", theError );
  1141.         DSpContext_FadeGammaIn( NULL, NULL );
  1142.         DSpContext_Release( theContext );
  1143.         return;
  1144.     }
  1145.  
  1146.     /* fade back in */
  1147.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  1148.     if( theError )
  1149.     {
  1150.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1151.         DSpContext_Release( theContext );
  1152.         return;
  1153.     }
  1154.     
  1155.     /* release the context */
  1156.     theError = DSpContext_Release( theContext );
  1157.     if( theError )
  1158.     {
  1159.         ErrorMessage( "DSpContext_Release", theError );
  1160.         return;
  1161.     }
  1162. }
  1163.  
  1164. /*
  1165. ********************************************************************************
  1166. **
  1167. ** Name: TestContextCLUT
  1168. **
  1169. ** Description:
  1170. **
  1171. **    Test the ability of DrawSprocket to manipulate the CLUT.
  1172. **
  1173. ********************************************************************************
  1174. */
  1175. void TestContextCLUT( void )
  1176. {
  1177.     DSpContextAttributes theDesiredAttributes;
  1178.     DSpContextReference theContext;
  1179.     OSStatus theError;
  1180.     RGBColor theBlankingColor;
  1181.     
  1182.     printf("\n\n");
  1183.     printf("############################################################\n");
  1184.     printf("###                     Testing CLUT                     ###\n");
  1185.     printf("############################################################\n");
  1186.     printf("\n\n");
  1187.  
  1188.  
  1189.     /* find the context */
  1190.     MyInitAttributes( &theDesiredAttributes );
  1191.     theDesiredAttributes.displayWidth            = 640;
  1192.     theDesiredAttributes.displayHeight            = 480;
  1193.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1194.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1195.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1196.     theDesiredAttributes.backBufferBestDepth    = 8;
  1197.     theDesiredAttributes.displayBestDepth        = 8;
  1198.     theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
  1199.     if( theError && kDSpContextNotFoundErr != theError )
  1200.     {
  1201.         ErrorMessage( "DSpFindBestContext", theError );
  1202.         return;
  1203.     }
  1204.     if( kDSpContextNotFoundErr == theError )
  1205.     {
  1206.         printf("# Unable to find a matching context for the following attributes:\n");
  1207.         DumpContextAttributes( &theDesiredAttributes );
  1208.         return;
  1209.     }
  1210.  
  1211.     /* reserve the context */    
  1212.     theError = DSpContext_Reserve( theContext, &theDesiredAttributes );
  1213.     if( theError )
  1214.     {
  1215.         ErrorMessage( "DSpContext_Reserve", theError );
  1216.         return;
  1217.     }
  1218.  
  1219.     /* set the blanking color to white, just for the heck of it */
  1220.     theBlankingColor.red = 0xFFFFF;    
  1221.     theBlankingColor.green = 0xFFFFF;    
  1222.     theBlankingColor.blue = 0xFFFFF;    
  1223.     theError = DSpSetBlankingColor( &theBlankingColor );
  1224.     if( theError )
  1225.     {
  1226.         ErrorMessage( "DSpSetBlankingColor", theError );
  1227.         return;
  1228.     }
  1229.  
  1230.     /* fade out all displays to black */
  1231.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  1232.     if( theError )
  1233.     {
  1234.         ErrorMessage( "DSpContext_FadeGammaOut", theError );
  1235.         DSpContext_FadeGammaIn( NULL, NULL );
  1236.         DSpContext_Release( theContext );
  1237.         return;
  1238.     }
  1239.     
  1240.     /* put the context into the active state */
  1241.     theError = DSpContext_SetState( theContext, kDSpContextState_Active );
  1242.     if( theError )
  1243.     {
  1244.         ErrorMessage( "DSpContext_SetState", theError );
  1245.         DSpContext_FadeGammaIn( NULL, NULL );
  1246.         DSpContext_Release( theContext );
  1247.         return;
  1248.     }
  1249.  
  1250.     /* fade back in */
  1251.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  1252.     if( theError )
  1253.     {
  1254.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1255.         DSpContext_Release( theContext );
  1256.         return;
  1257.     }
  1258.     
  1259.     /*
  1260.     ****************************************************************************
  1261.     ** do the CLUT testing
  1262.     ****************************************************************************
  1263.     */
  1264.     
  1265.     /* draw a pattern into the back buffer and cycle it */
  1266.     {
  1267.     UInt32 thePosition, theColorIndex, theXPos, theYPos;
  1268.     CGrafPtr theBackBuffer;
  1269.     ColorSpec theOriginalColors[256];
  1270.     Rect theRect;
  1271.     
  1272.     /* get the back buffer */
  1273.     theError = DSpContext_GetBackBuffer( theContext, kDSpBufferKind_Normal,
  1274.         &theBackBuffer );
  1275.     if( theError )
  1276.     {
  1277.         ErrorMessage( "DSpContext_GetBackBuffer", theError );
  1278.         DSpContext_Release( theContext );
  1279.         return;
  1280.     }
  1281.     
  1282.     /* set the back buffer to be the current port */
  1283.     SetPort( (GrafPtr)theBackBuffer );
  1284.  
  1285.     /* draw a pattern into the back buffer */
  1286.     theColorIndex = 0;
  1287.     for( theYPos = 0; theYPos < theDesiredAttributes.displayHeight;
  1288.         theYPos += kRectSize )
  1289.     {
  1290.         for( theXPos = 0; theXPos < theDesiredAttributes.displayWidth;
  1291.             theXPos += kRectSize )
  1292.         {
  1293.             Rect theRect;
  1294.             
  1295.             SetRect( &theRect, 0, 0, kRectSize, kRectSize );
  1296.             OffsetRect( &theRect, theXPos, theYPos );
  1297.             theBackBuffer->fgColor = theColorIndex % 255;
  1298.             
  1299.             PaintRect( &theRect );
  1300.  
  1301.             theColorIndex++;            
  1302.         }
  1303.     }
  1304.     
  1305.     /* bring the back buffer to the front */
  1306.     theError = DSpContext_SwapBuffers( theContext, NULL, 0 );
  1307.     if( theError )
  1308.     {
  1309.         ErrorMessage( "DSpContext_SwapBuffers", theError );
  1310.         DSpContext_Release( theContext );
  1311.         return;
  1312.     }
  1313.     
  1314.     /*
  1315.     ** get the original color table
  1316.     **
  1317.     ** unfortunately, these probably aren't the real colors, since
  1318.     ** the way that gamma works on the Mac is to remap the indexed
  1319.     ** color table to new colors.  In other words, these colors are
  1320.     ** gamma corrected versions of the ones that were originally set.
  1321.     **
  1322.     */
  1323.     theError = DSpContext_GetCLUTEntries( theContext, theOriginalColors,
  1324.         0, 255 );
  1325.     if( theError )
  1326.     {
  1327.         ErrorMessage( "DSpContext_GetCLUTEntries", theError );
  1328.         DSpContext_Release( theContext );
  1329.         return;
  1330.     }
  1331.     
  1332.     /* cycle the colors */
  1333.     while( !Button() )
  1334.     {
  1335.         ColorSpec theSpec[256], theTempSpec;
  1336.         
  1337.         /* rotate them */
  1338.         theTempSpec = theOriginalColors[0];
  1339.         
  1340.         for( theColorIndex = 0; theColorIndex < 255; theColorIndex++ )
  1341.             theSpec[theColorIndex].rgb =
  1342.                 theOriginalColors[(theColorIndex + thePosition) % 255].rgb;
  1343.  
  1344.         theSpec[255].rgb = theTempSpec.rgb;
  1345.         
  1346.         thePosition++;
  1347.         if( thePosition > 255 )
  1348.             thePosition = 0;
  1349.         
  1350.         /* set the entries */
  1351.         theError = DSpContext_SetCLUTEntries( theContext, theSpec, 0, 255 );
  1352.         if( theError )
  1353.         {
  1354.             ErrorMessage( "DSpContext_SetCLUTEntries", theError );
  1355.             DSpContext_Release( theContext );
  1356.             return;
  1357.         }
  1358.     }
  1359.  
  1360.     }
  1361.     
  1362.     /*
  1363.     ****************************************************************************
  1364.     ** cleanup
  1365.     ****************************************************************************
  1366.     */    
  1367.  
  1368.     /* fade to black */
  1369.     theError = DSpContext_FadeGammaOut( NULL, NULL );
  1370.     if( theError )
  1371.     {
  1372.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1373.         DSpContext_Release( theContext );
  1374.         return;
  1375.     }
  1376.  
  1377.     /* put the context into the inactive state */
  1378.     theError = DSpContext_SetState( theContext, kDSpContextState_Inactive );
  1379.     if( theError )
  1380.     {
  1381.         ErrorMessage( "DSpContext_SetState", theError );
  1382.         DSpContext_FadeGammaIn( NULL, NULL );
  1383.         DSpContext_Release( theContext );
  1384.         return;
  1385.     }
  1386.  
  1387.     /* fade back in */
  1388.     theError = DSpContext_FadeGammaIn( NULL, NULL );
  1389.     if( theError )
  1390.     {
  1391.         ErrorMessage( "DSpContext_FadeGammaIn", theError );
  1392.         DSpContext_Release( theContext );
  1393.         return;
  1394.     }
  1395.     
  1396.     /* release the context */
  1397.     theError = DSpContext_Release( theContext );
  1398.     if( theError )
  1399.     {
  1400.         ErrorMessage( "DSpContext_Release", theError );
  1401.         return;
  1402.     }
  1403. }
  1404.  
  1405. void
  1406. TestUserSelectContext( void )
  1407. {
  1408.     DSpContextAttributes theDesiredAttributes;
  1409.     DSpContextAttributes theActualAttributes;
  1410.     DSpContextReference theContext;
  1411.     OSStatus theError;
  1412.     RGBColor theBlankingColor;
  1413.     Boolean theShowDialogFlag;
  1414.     DisplayIDType theDisplayID;
  1415.     
  1416.     printf("\n\n");
  1417.     printf("############################################################\n");
  1418.     printf("###                     Testing CLUT                     ###\n");
  1419.     printf("############################################################\n");
  1420.     printf("\n\n");
  1421.  
  1422.  
  1423.     /* find the context */
  1424.     MyInitAttributes( &theDesiredAttributes );
  1425.     theDesiredAttributes.displayWidth            = 640;
  1426.     theDesiredAttributes.displayHeight            = 480;
  1427.     theDesiredAttributes.colorNeeds                = kDSpColorNeeds_Require;
  1428.     theDesiredAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  1429.     theDesiredAttributes.displayDepthMask        = kDSpDepthMask_8;
  1430.     theDesiredAttributes.backBufferBestDepth    = 8;
  1431.     theDesiredAttributes.displayBestDepth        = 8;
  1432.  
  1433.     /*
  1434.     ** see if there are enough choices available for the user to
  1435.     ** choose from, this can be used if I needed to determine
  1436.     ** whether or not to enable a menu item, etc.
  1437.     */
  1438.     theError = DSpCanUserSelectContext( &theDesiredAttributes,
  1439.         &theShowDialogFlag );
  1440.     if( theError )
  1441.     {
  1442.         ErrorMessage( "DSpCanUserSelectContext", theError );
  1443.         return;
  1444.     }
  1445.     if( false == theShowDialogFlag )
  1446.     {
  1447.         printf("There are not enough choices to warrant asking the user.\n");
  1448.         return;
  1449.     }
  1450.     
  1451.     /*
  1452.     ** put up the choice dialog, I don't care about what display it
  1453.     ** appears on, nor do I care to know about update events
  1454.     */
  1455.     theError = DSpUserSelectContext( &theDesiredAttributes, 0,
  1456.         NULL, &theContext );
  1457.     if( theError )
  1458.     {
  1459.         /*
  1460.         ** since we know that there were possible matches available (because
  1461.         ** we called DSpCanUserSelectContext), we know that a context-not-found
  1462.         ** error means that the user canceled the dialog
  1463.         */
  1464.         if( kDSpContextNotFoundErr == theError )
  1465.             printf("The user canceled the dialog.\n");
  1466.         else
  1467.             ErrorMessage( "DSpUserSelectContext", theError );
  1468.         return;
  1469.     }
  1470.  
  1471.     /* tell the user about the results */
  1472.     printf("User-Selected Context for the following attributes...\n");
  1473.     DumpContextAttributes( &theDesiredAttributes );
  1474.     
  1475.     theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
  1476.     if( theError )
  1477.     {
  1478.         ErrorMessage( "DSpContext_GetDisplayID", theError );
  1479.         return;
  1480.     }
  1481.  
  1482.     theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
  1483.     if( theError )
  1484.     {
  1485.         ErrorMessage( "DSpContext_GetAttributes", theError );
  1486.         return;
  1487.     }
  1488.  
  1489.     printf("...is the context on display id %d with these attributes:\n",
  1490.         theDisplayID );
  1491.     DumpContextAttributes( &theActualAttributes );
  1492. }
  1493.